home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / SW Demo / Demo Source / TEHandler.c < prev    next >
Encoding:
Text File  |  1994-11-08  |  8.0 KB  |  298 lines  |  [TEXT/MPCC]

  1. // ----------------------------------------------------------------------------------
  2. // TEHanlder.c
  3. // ----------------------------------------------------------------------------------
  4. // Handles most of the important routines related to the text window's TE.
  5. //
  6. // ----------------------------------------------------------------------------------
  7. // History:
  8. //    9/20/94        CG    Original
  9. //    10/4/94        CG    Tried to fix the scroll to text sync after a paste or TEKey.
  10. //                    It still needs some fine tuning.
  11.  
  12. #include "TEHandler.h"
  13. #include "WindowHandler.h"
  14. #include "Globals.h"
  15.  
  16. void SetView(WindowPtr theWindow);
  17. void AdjustText(TEHandle TEH);
  18. void SetScrollBar();
  19. void DoTEKey(WindowPtr theWindow, char theChar);
  20. void DoControl(WindowPtr theWindow, ControlHandle theControl, short partCode, Point where);
  21. pascal void TrackScrollBar(ControlHandle theControl, short partCode);
  22. Boolean TrackContentClick(void);
  23. void SizeScroll(ControlHandle theControl, WindowPtr theWindow);
  24.  
  25. short gPageLines;
  26.  
  27. // ----------------------------------------------------------------------------------
  28. // ----------------------------------------------------------------------------------
  29. // DoControl
  30. // ----------------------------------------------------------------------------------
  31. // Handle a mouse click in a scroll bar.  Right now auto scrolling with the thumb
  32. // isn't implemented.
  33.  
  34. void DoControl( WindowPtr theWindow, ControlHandle theControl, 
  35.         short partCode, Point where )
  36. {
  37.     ControlActionUPP    theAction;
  38.     short    oldV;
  39.     short    newV;
  40.  
  41.     gDocWindow = theWindow;        // so our control handler can get window data
  42.  
  43.     switch ( partCode )
  44.     {
  45.         case inUpButton:
  46.         case inDownButton:
  47.         case inPageUp:
  48.         case inPageDown:
  49.             theAction = NewControlActionProc((ProcPtr) TrackScrollBar);
  50.             TrackControl( theControl, where, theAction );
  51.             break;
  52.         case inThumb:
  53.             oldV = GetCtlValue( theControl );
  54.             TrackControl( theControl, where, (ControlActionUPP) nil );    // add later
  55.             SetScrollBar();
  56.             break;    
  57.     } // switch
  58.  
  59.     return;
  60.     
  61. } // DoControl
  62.  
  63.  
  64. // ----------------------------------------------------------------------------------
  65. // TrackScrollBar
  66. // ----------------------------------------------------------------------------------
  67. // This is the callback routine that handles tracking the scrollbar.  This is for
  68. // when you continue to hold the mouse down in a scrollbar and want it to continue
  69. // scrolling.
  70.  
  71. pascal void TrackScrollBar( ControlHandle theControl, short partCode )
  72. {
  73.     int pageSize;
  74.     int    amount;
  75.     int    oldval;
  76.  
  77.     WinDocRecord    **theData;
  78.     TEHandle        theTE;
  79.     
  80.     theData = (WinDocRecord**) GetWRefCon(gDocWindow);
  81.     theTE = (**theData).DocTE;
  82.     
  83.     pageSize = ((**theTE).viewRect.bottom - (**theTE).viewRect.top) / (**theTE).lineHeight - 1;
  84.     
  85.     switch ( partCode ){
  86.         case inUpButton:
  87.             amount = -1;
  88.             break;
  89.         case inDownButton:
  90.             amount = 1;
  91.             break;
  92.         case inPageUp:
  93.             amount = - pageSize;
  94.             break;
  95.  
  96.         case inPageDown:
  97.             amount = pageSize;
  98.             break;
  99.             
  100.     } // switch
  101.     
  102.     oldval = GetCtlValue(theControl);
  103.     SetCtlValue(theControl, oldval + amount);
  104.     SetScrollBar();
  105.     
  106.     return;
  107.     
  108. } // TrackScrollBar
  109.  
  110.  
  111.  
  112. // ----------------------------------------------------------------------------------
  113. // TrackContentClick
  114. // ----------------------------------------------------------------------------------
  115. // Handles clicks in the window.
  116.  
  117. Boolean TrackContentClick( void )
  118. {
  119.     Point            where;
  120.     Rect            viewRect;
  121.     TEHandle        theTE;
  122.     ControlHandle    theControl;
  123.     GrafPtr            thePort;
  124.     RgnHandle        oldClip;
  125.     Rect            scrollRect;
  126.     Boolean            needRedraw;
  127.     
  128.     GetPort( &thePort );
  129.     SetPort( gDocWindow );
  130.  
  131.     GetMouse( &where );
  132.  
  133.     theTE = (TEHandle)GetWRefCon( gDocWindow );
  134.     
  135.     viewRect = (*theTE)->viewRect;
  136.     
  137.     theControl = ((WindowPeek)gDocWindow)->controlList;        /* We know there's 1 control */
  138.  
  139.     needRedraw = false;
  140.  
  141.     // If the mouse is above or below the window, we fake a mouse click on the scroll bar
  142.     if ( where.v < viewRect.top )
  143.     {    TrackScrollBar( theControl, inUpButton );
  144.         needRedraw = true;
  145.     } else if ( where.v > viewRect.bottom )
  146.     {    TrackScrollBar( theControl, inDownButton );
  147.         needRedraw = true;
  148.     }
  149.     
  150.  
  151.     // redraw the window
  152.     
  153.     if ( needRedraw )
  154.     {     oldClip = NewRgn();
  155.         if ( oldClip )
  156.         {    GetClip( oldClip );
  157.             scrollRect = (*theControl)->contrlRect;
  158.             ClipRect( &scrollRect );
  159.             Draw1Control( theControl );
  160.             SetClip( oldClip );
  161.             DisposeRgn( oldClip );
  162.         } // if
  163.     } // if
  164.  
  165.     SetPort( thePort );
  166.  
  167.     return true;
  168.     
  169. } // TrackContentClick
  170.  
  171. // ----------------------------------------------------------------------------------
  172. // SizeScroll
  173. // ----------------------------------------------------------------------------------
  174. // Handles resizing the control in response to growWindow.
  175.  
  176. void SizeScroll(ControlHandle theControl, WindowPtr theWindow)
  177. {
  178.     MoveControl( theControl, theWindow->portRect.right - 15, -1 );
  179.     SizeControl( theControl, 16, theWindow->portRect.bottom - theWindow->portRect.top - 13 );
  180.  
  181.     return;
  182. } // SizeScroll
  183.  
  184.  
  185. // ----------------------------------------------------------------------------------
  186. // TEAdjustView
  187. // ----------------------------------------------------------------------------------
  188. // This basically adjusts the view so that the scrollbars will fit and to adjust the 
  189. // size of the TEView when the window's size changes.
  190.  
  191. void TEAdjustView(WindowPtr theWindow, TEHandle theTE)
  192. {
  193.     Rect    TERect;
  194.     short    offset;
  195.     Rect    WindowRect;
  196.     
  197.     WindowRect = theWindow->portRect;
  198.     
  199.     TERect.left = WindowRect.left;
  200.     TERect.right = WindowRect.right - 15;
  201.     TERect.bottom = WindowRect.bottom;
  202.     TERect.top = WindowRect.top;
  203.     
  204.     InsetRect(&TERect, 4, 4);
  205.     
  206.     (*theTE)->viewRect = TERect;
  207.     (*theTE)->destRect = TERect;
  208.     
  209.     TECalText(theTE);
  210.     
  211. } // TEAdjustView
  212.  
  213.  
  214. void ShowSelect(TEHandle theTE, ControlHandle theControl)
  215. {
  216.     register int n, topLine, bottomLine, linesInScreen;
  217.  
  218.     linesInScreen = ((**theTE).viewRect.bottom - (**theTE).viewRect.top)/(**theTE).lineHeight;
  219.  
  220.     n = (**theTE).nLines - linesInScreen;
  221.  
  222.     // correct for ending CR bug in TE
  223.     if ( (**theTE).teLength > 0 && (*((**theTE).hText))[(**theTE).teLength - 1] == '\r')
  224.         n++;
  225.     
  226.     SetCtlMax(theControl, n > 0 ? n : 0);
  227.     
  228.     topLine = GetCtlValue(theControl);
  229.     bottomLine = topLine + linesInScreen;
  230.  
  231.     if ((**theTE).selStart < (**theTE).lineStarts[topLine] ||
  232.             (**theTE).selStart >= (**theTE).lineStarts[bottomLine])
  233.     {    for (n = 0; (**theTE).selStart >= (**theTE).lineStarts[n]; n++)
  234.             ;
  235.         SetCtlValue(theControl, n - linesInScreen/2);
  236.     }
  237.     SetScrollBar();
  238. }
  239.  
  240.  
  241.  
  242. // ----------------------------------------------------------------------------------
  243. // SetScrollBar
  244. // ----------------------------------------------------------------------------------
  245. // This is a tricky routine that doesn't work terribly well right now.  Basically
  246. // it attempts to sync the scrollbars with the text.  It further tries to keep
  247. // the insertion point in a reasonable place in the window for typing.  
  248. // Unfortunately this leads to some annoying 'jumps' in the text at times.  I
  249. // really need to just sit down and fiddle with this.  Right now it is basically
  250. // a collection of various hacks found in editors from the net.  
  251. //
  252. // This, along with menu feedback, are the two main things I need to fix in the
  253. // editor. 
  254.  
  255. void SetScrollBar()
  256. {
  257.     int        oldScroll, newScroll, delta;
  258.     
  259.     
  260.     
  261.     ControlHandle theControl;
  262.     WinDocRecord    **theData;
  263.     TEHandle        theTE;
  264.     
  265.     theData = (WinDocRecord**) GetWRefCon(gDocWindow);
  266.     theControl = (*theData)->DocVScroll;
  267.     theTE = (*theData)->DocTE;
  268.     oldScroll = (**theTE).viewRect.top - (**theTE).destRect.top;
  269.     newScroll = GetCtlValue(theControl) * (**theTE).lineHeight;
  270.     delta = oldScroll - newScroll;
  271.     
  272.     if (delta != 0)
  273.         TEScroll(0, delta, theTE);
  274.     
  275. } // SetScrollBar
  276.  
  277.  
  278.  
  279. // ----------------------------------------------------------------------------------
  280. // DoTEKey
  281. // ----------------------------------------------------------------------------------
  282. // Handles a keypress.  It sends the character to the TE library.
  283.  
  284. void DoTEKey(WindowPtr theWindow, char theChar)
  285. {    TEHandle        theTE;
  286.     WinDocRecord    **theData;
  287.     
  288.     theData = (WinDocRecord**) GetWRefCon(theWindow);
  289.     theTE = (**theData).DocTE;    
  290.     
  291.     TEKey(theChar, theTE);
  292.     ObscureCursor();
  293.  
  294.     ShowSelect(theTE, (**theData).DocVScroll);    
  295.     (**theData).dirty = TRUE;
  296.     
  297. } // DoTEKey
  298.